package com.miron.client;

import org.cobogw.gwt.waveapi.gadget.client.StateUpdateEvent;
import org.cobogw.gwt.waveapi.gadget.client.StateUpdateEventHandler;
import org.cobogw.gwt.waveapi.gadget.client.WaveGadget;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.gadgets.client.Gadget;
import com.google.gwt.gadgets.client.UserPreferences;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;

/**
 * 
 * Initialization of the gadget is performed here. It also stores the buttons
 * and the label displaying counter's value.
 * 
 * It extends the {@link WaveGadget} class to be able to register for state
 * change events. {@link WaveGadget} is hosted <a
 * href="http://code.google.com/p/cobogwave/">here</a>.
 * 
 * @author Miron Sadziak mironsadziak@gmail.com
 */
@Gadget.ModulePrefs(title = "Simple SynchronizedInteger")
public class SimpleCounter extends WaveGadget<UserPreferences> {

	/**
	 * Key used for accessing the counter value in wave's shared state.
	 */
	public final static String counterKey = "counterKey";

	/**
	 * Value of the counter as a wave's synchronized integer
	 */
	private SynchronizedInteger counter;

	/**
	 * Label displaying the value of the counter
	 */
	private final Label counterLabel = new Label();

	/**
	 * Button for incrementing the counter
	 */
	private final Button incrementButton = new Button("Increment");

	/**
	 * Button for decrementing the counter
	 */
	private final Button decrementButton = new Button("Decrement");

	/**
	 * Initializes the gadget. Adds event handlers for buttons and for wave's
	 * state change.
	 * 
	 * @param preferences
	 *            Gadget's user preferences
	 */
	@Override
	protected void init(UserPreferences preferences) {

		// Creates a new instance of SynchronizedInteger for the counter
		counter = new SynchronizedInteger(counterKey, getWave());

		// Default display value of the counter
		counterLabel.setText("Value: " + counter.getValue());

		// Event handlers for increment and decrement buttons
		// First they update the local counter's value to the new value
		// and then they store the new value in wave's shared state
		incrementButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				counter.setValue(counter.getValue() + 1);
				counterLabel.setText("Value: " + counter.getValue());
			}
		});
		decrementButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				counter.setValue(counter.getValue() - 1);
				counterLabel.setText("Value: " + counter.getValue());
			}
		});

		// Adding the ui elements to the root panel
		RootPanel.get().add(counterLabel);
		RootPanel.get().add(incrementButton);
		RootPanel.get().add(decrementButton);

		// Registering a wave's state handler for changing the label displaying
		// counter's value.
		getWave().addStateUpdateEventHandler(new StateUpdateEventHandler() {
			public void onUpdate(StateUpdateEvent event) {

				// When somebody changes the counter's value, integer stored
				// in variable 'counter' will be automatically synchronized (so
				// that
				// the call below to getValue() will return an up-to-date
				// value), but
				// we also need to update the label displaying it.
				counterLabel.setText("Value: " + counter.getValue());
			}
		});
	}
}
